package com.icebergteam.warfacewidget.wiki.ui;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Stack;
import java.util.regex.Pattern;
import com.icebergteam.warfacewidget.R;
import com.icebergteam.warfacewidget.core.LogManager;
import com.icebergteam.warfacewidget.core.asynctaskmanager.AsyncTaskManager;
import com.icebergteam.warfacewidget.core.asynctaskmanager.IHandleMessage;
import com.icebergteam.warfacewidget.core.asynctaskmanager.IProgressTracker;
import com.icebergteam.warfacewidget.core.asynctaskmanager.TaskProgress;
import com.icebergteam.warfacewidget.core.utils.ViewUtils;
import com.icebergteam.warfacewidget.news.ui.NewsActivity;
import com.icebergteam.warfacewidget.ui.TwitchTVVideoPlayerActivity;
import com.icebergteam.warfacewidget.ui.YouTubeVideoPlayerActivity;
import com.icebergteam.warfacewidget.wiki.data.WikiDownloadTask;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

public class WikiActivity extends Activity implements IHandleMessage,
IProgressTracker{
	public static String className = WikiActivity.class.getCanonicalName();
	public static final String KEY_CURRENT_URL = String.format("%s.KEY_CURRENT_URL", className);
	public static final String KEY_LIST_URL = String.format("%s.KEY_LIST_URL", className);
	public static final String homeWikiHtmlPage = "http://wf.mail.ru/wiki/index.php/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0";

	private AsyncTaskManager asyncTaskManager;
	private JIFace iface = new JIFace();
	private int heightActionBar = 96;
	private ProgressBar progressBar;
	private Stack<String> listUrl = new Stack<String>();
	private WebView wikiWebView;
	private WikiDownloadTask wikiDownloadTasks;
	private String currentUrl = homeWikiHtmlPage;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_wiki);
		try {	
			
			// Create manager and set this activity as context and listener
			asyncTaskManager = new AsyncTaskManager(this, this);
					// Handle task that can be retained before
			asyncTaskManager.handleRetainedTask(getLastNonConfigurationInstance());
			
			getActionBar().setDisplayHomeAsUpEnabled(true);
			
			this.currentUrl = getIntent().getStringExtra(WikiActivity.KEY_CURRENT_URL);
			if(savedInstanceState != null){
				this.heightActionBar = savedInstanceState
						.getInt(NewsActivity.KEY_HEIGHT_ACTION_BAR);
				this.currentUrl = savedInstanceState.getString(WikiActivity.KEY_CURRENT_URL);
				ByteArrayInputStream byteArray = new ByteArrayInputStream((byte[]) savedInstanceState.get(WikiActivity.KEY_LIST_URL));
		        ObjectInputStream inputStreamo = new ObjectInputStream(byteArray);
				this.listUrl = (Stack<String>) inputStreamo.readObject();
			}
		        
			setViews();
			setValues();
		} catch (StreamCorruptedException e) {
			LogManager.LogEA(className, ViewUtils.getErrorMessage(e));
		} catch (IOException e) {
			LogManager.LogEA(className, ViewUtils.getErrorMessage(e));
		} catch (ClassNotFoundException e) {
			LogManager.LogEA(className, ViewUtils.getErrorMessage(e));
		}
	}
		
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		try {
			outState.putInt(NewsActivity.KEY_HEIGHT_ACTION_BAR,
					this.heightActionBar);
			outState.putString(WikiActivity.KEY_CURRENT_URL, this.currentUrl);
			ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
		    ObjectOutputStream outputStream = new ObjectOutputStream(byteArray);
		    outputStream.writeObject(listUrl);
			outState.putByteArray(WikiActivity.KEY_LIST_URL, byteArray.toByteArray());
		} catch (IOException e) {
			LogManager.LogEA(className, ViewUtils.getErrorMessage(e));
		}
		super.onSaveInstanceState(outState);
	}
	
	@Override
	@Deprecated
	public Object onRetainNonConfigurationInstance() {
		return asyncTaskManager.retainTask();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.wikiactivity_menu, menu);
		
		MenuItem updateMenuItem = menu.add(Menu.NONE, R.id.action_update, Menu.NONE, R.string.action_update);
		updateMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
		Drawable iconUpdate = getResources().getDrawable(R.drawable.widget_update_icon);
		
		// FIXME: getAction().getHeight get null when rotate screen Android
					// 4.1.2
		if (getActionBar().getHeight() != 0) {
			this.heightActionBar = getActionBar().getHeight();
		}
			
		updateMenuItem.setIcon(ViewUtils.scaleImage(
			iconUpdate, this.heightActionBar ));
		
		return true;
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch(item.getItemId()){
		case R.id.action_exit:
			this.finish();
			break;
		case R.id.action_update:
			this.update();
			break;
		case android.R.id.home:
			if(!backWikiHtmlPage()){
				finish();
			}
				
			break;
			default:break;
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	public void setViews(){
		this.wikiWebView = (WebView) findViewById(R.id.wiki_activity_webView);
		this.progressBar = (ProgressBar) findViewById(R.id.wiki_activity_progressBar);
		this.progressBar.setProgress(0);
		this.progressBar.setVisibility(View.GONE);
		
		WebSettings localWebSettings = this.wikiWebView.getSettings();
        localWebSettings.setJavaScriptEnabled(true);
        this.wikiWebView.addJavascriptInterface(iface, "droid");
        localWebSettings.setAllowFileAccess(true);
        localWebSettings.setBuiltInZoomControls(true);
        localWebSettings.setUseWideViewPort(true);
        localWebSettings.setLoadWithOverviewMode(true);

      //  this.wikiWebView.setBackgroundColor(0);
       // this.wikiWebView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
        this.wikiWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY );
        this.wikiWebView.setWebChromeClient(new WebChromeClient(){
        	@Override
			public void onProgressChanged(WebView view, final int newProgress) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						WikiActivity.this.progressBar.setProgress(newProgress);
					}
				});
				super.onProgressChanged(view, newProgress);
			}
        });
        this.wikiWebView.setWebViewClient(new WebViewClient(){
			@Override
			public void onPageStarted(WebView view, String url, Bitmap favicon) {
				WikiActivity.this.progressBar.setVisibility(View.VISIBLE);
				WikiActivity.this.progressBar.setProgress(0);
				super.onPageStarted(view, url, favicon);
			}
			@Override
			public void onPageFinished(WebView view, String url) {
				WikiActivity.this.progressBar.setVisibility(View.GONE);
				super.onPageFinished(view, url);
			}
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				LogManager.LogVA(className, url);
				
				if(YouTubeVideoPlayerActivity.initByUrl(url, WikiActivity.this)){
            		LogManager.LogV(className, LogManager.getExecuteMethodName() + " check url - youtube", url);
            	}
            	else if(TwitchTVVideoPlayerActivity.initByUrl(url,  WikiActivity.this)){
            		LogManager.LogV(className, LogManager.getExecuteMethodName() + " check url - twitch", url);
            	}
		       	else if(!isWikiHtmlUrl(url)){
            		Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					intent.setData(Uri.parse(url));
					startActivity(Intent.createChooser(intent, getString(R.string.news_page_choose)));
            	}
				else{
					startLoadHtmlPage(url, true, false);
				}
				return true;
			}
		});
	}

	private boolean isWikiImageUrl(String url){
		return url!= null && Pattern.compile("([^\\s]+(\\.(?i)(jpg|png|gif|bmp))$)").matcher(url).matches() && !url.contains(".php");
	}
	
	private boolean isWikiHtmlUrl(String url){
		return url!= null && !isWikiImageUrl(url) && url.contains("wf.mail.ru/wiki");
	}

	@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
        	if(!backWikiHtmlPage()){
        		finish();
        	}
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
	
	public boolean backWikiHtmlPage(){
		if(!listUrl.isEmpty() && listUrl.size() > 1 ) {
            listUrl.pop();
        	startLoadHtmlPage(listUrl.pop(), true, false);
        	return true;
		}
		return false;
	}
	
	public void setValues(){
		if(!asyncTaskManager.isWorking()){
			startLoadHtmlPage(currentUrl, true, false);
		}
	}
	
	private void startLoadHtmlPage(String url, Boolean cache, Boolean update){
		this.currentUrl =url;
		
		this.wikiDownloadTasks = new WikiDownloadTask( new TaskProgress(getString(R.string.wait)), this, url, cache, update);
		this.wikiDownloadTasks.setCancelableTask(false);
		this.asyncTaskManager.setupTask(wikiDownloadTasks);
		this.wikiDownloadTasks.execute();
	}
	
		/* class for js injections */
		class JIFace {
			public void playYoutubeVideo(String id){
				LogManager.LogVA(className, id);
				YouTubeVideoPlayerActivity.initById(id, WikiActivity.this);
			}
			
			public void playTwitchVideo(final String url){
				LogManager.LogVA(className, url);
				TwitchTVVideoPlayerActivity.initByUrl(url, WikiActivity.this);
			}
			
			public void errorObjectTag(){
				LogManager.LogVA(className);

				ViewUtils.errorDialog(getString(R.string.title_activity_wiki), WikiActivity.this.getString(R.string.news_page_error_object_tag), WikiActivity.this.getString(android.R.string.ok) , null, null, null, WikiActivity.this);
			}
			
			public void zoomImage(String uri){
				LogManager.LogVA(className);
				Intent intent = new Intent();
				intent.setAction(Intent.ACTION_VIEW);
				intent.setDataAndType(Uri.parse(uri), "image/*");
				startActivity(intent);
			}
		};
		
	public void onDestroy() {
		LogManager.LogVA(className);
		super.onDestroy();	
	}
		
	public void abort(){
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				WikiActivity.this.wikiWebView.stopLoading();
			}
		});
		if(this.wikiDownloadTasks !=null){
			this.wikiDownloadTasks.abort();	
			
		}
	}
		
	public void update(){
		this.abort();
		this.startLoadHtmlPage(this.currentUrl, true, true);
	}

	@Override
	public void onProgress(TaskProgress message) {
		
	}
	
	@Override
	public void onComplete(String className, final Object... params) {
		boolean update = (Boolean) ((params!= null && params.length > 2)? params[2]:null); 
		LogManager.LogEA(className, update);
		if((listUrl.isEmpty()) || (listUrl.size()> 0 && !listUrl.lastElement().equals(this.currentUrl) && !update )){
			listUrl.push(this.currentUrl);
			LogManager.LogEA(className, this.currentUrl, listUrl);
		}
		this.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				if(params!= null && params.length > 1 && params[1].equals(WikiDownloadTask.CODE_OK))
				wikiWebView.loadDataWithBaseURL("", (String) params[0], "text/html", "UTF-8", "");
				else{
					WikiActivity.this.backWikiHtmlPage();
				}
			}
   		});
	}
	

	@Override
	public void onCanceled(String className, Object... params) {
		
	}

	@Override
	public void handleMessage(final String title, final String string) {
		runOnUiThread(new Runnable() {
			
			@Override
			public void run() {
				Toast.makeText(WikiActivity.this, string, Toast.LENGTH_LONG).show();
			}
		});
	}

	@Override
	public void handleError(String title, final String string) {
		
		runOnUiThread(new Runnable() {
			
			@Override
			public void run() {
				Toast.makeText(WikiActivity.this, string, Toast.LENGTH_LONG).show();
			}
		});
		
	}
}